<template>
	<div :style="{ display: 'flex', flex: 1, flexBasis: 'auto', flexDirection: 'column', }">
		<!-- 头部 -->
		<Matchheader v-bind="{
			time, submit, title: match ? match.name : '',
			save, savetime, saveloading, match, isMatch,
			index: Number(index),
			questionlist: list,
			userquestion: matchuser?.userquestion || [],
			routername: '比赛答题',
		}">
		</Matchheader>

		<!-- 主体-代码题 -->
		<Question ref="ques" v-if="question && question.type === '代码'" v-bind="{
			question,
			questionlist: list,
			index: Number(index),
			setuserdata,
			userdata,
			match, isMatch,
			submit
		}">
		</Question>

		<!-- 主体-非代码题目 -->
		<questionselect ref="select" v-if="question && question.type !== '代码'" v-bind="{
			question,
			questionlist: list,
			index: Number(index),
			setuserdata,
			userdata,

			match, isMatch, submit
		}">
			<!-- <Matchfooter v-bind="{
    index: Number(index),
    questionlist: list,
    userquestion: matchuser?.userquestion || []
  }">
      </Matchfooter> -->
		</questionselect>
		<!-- 试卷提交内容确认 -->
		<el-dialog v-model="dialogVisible" title="Tips" width="80%" align-center class="dialog">
			<template #header>
				<span class="icon-text el-dialog__header-title">
					<el-icon class="text-primary">
						<Guide />
					</el-icon>
					试卷提交内容确认
				</span>
			</template>
			<div>
				<el-row :gutter="10" class="dialog-body">
					<el-col :span="12" class="dialog-body-left">
						<el-scrollbar>
							<el-table border :height="`calc(75vh - 2px)`" :data="userQuestion" style="width: 100%"
								@row-click="clickRow" :row-class-name="rowClassName">
								<el-table-column type="index" label="题目" width="60" />
								<!-- <el-table-column prop="" label="题目编号" width="" /> -->
								<el-table-column prop="type" label="类型" width="60" />
								<!-- show-overflow-tooltip -->
								<el-table-column prop="context" label="题目描述">
									<template #default="{ row }">
										<span v-html="row.context"></span>
									</template>
								</el-table-column>
								<el-table-column prop="bytes" label="我的提交" width="100" show-overflow-tooltip />
							</el-table>
						</el-scrollbar>
					</el-col>
					<el-col :span="12" class="dialog-body-right">
						<el-scrollbar>
							<div class="to-question">
								<el-button type="primary" @click="toQuestion">跳转题目</el-button>
							</div>
							<pre class="mySubmit" v-if="currCheckUq?.type === '代码'" v-highlight
								:class="'language-' + currCheckUq?.language">
					<code v-text="currCheckUq?.mySubmit" class="code-pre"></code>
				</pre>
							<pre v-else v-highlight :class="'language-' + currCheckUq?.language">
					<code v-text="currCheckUq?.mySubmit" class="code-pre"></code>
				</pre>
						</el-scrollbar>
					</el-col>
				</el-row>
			</div>
			<template #footer>
				<div class="dialog-footer">
					<el-button type="primary" @click="toSubmit">确认提交</el-button>
				</div>
			</template>
		</el-dialog>

	</div>
</template>

<script setup lang="ts">

import { useLocalStorage } from "@vueuse/core";
import { ElMessage, ElMessageBox } from "element-plus";
import moment from "moment";
import { Socket } from "socket.io-client";
import { assign } from "underscore";
import {
	computed,
	onMounted,
	ref,
	toRefs,
	watch
} from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import {
	Apimatchuserquestion,
	asyncgettmpmatchuserdata,
	asyncSaveMatch,
	asyncsavetmpmatchuserdata,
	asyncselectmatchquestion,
	jilurizhi,
} from "../../../api";
import { Storekey } from "../../../interface";
import { IWsEmitatactivity } from "../../../mysql_interface";
import Studycodemodel from "../../../mysql_interface/studycodemodel";
import { markdownhtml } from "../../../util/htmlstring";
import { SMP } from "./interface";
import Matchheader from "./matchheader.vue";
import Question from "./question.vue";
import questionselect from "./questionselect.vue";

const p = defineProps<{
	index: string
	match: SMP["match"],
	time: SMP["time"],
	matchuser?: Apimatchuserquestion,
	start: Function,
	isnot: { err: number; msg: string }
	setresult: Function,
	sub: Boolean,
}>()
const { index, isnot, matchuser } = toRefs(p);
const isMatch = true

const list = ref<Studycodemodel.Imatchquestion[]>([]);
const store = useStore(Storekey);

const router = useRouter();
const user = computed<Studycodemodel.Iuser>(() => {
	return store.getters.getuser;
});

const ques = ref<typeof Question>();
const select = ref<typeof questionselect>();
// 
const userdata_ = useLocalStorage<Record<string, any>>(`${p.match.ID}-${user.value.ID}`, {}) // reactive<Record<string, any>>({});
const userdata = userdata_.value

const question = computed(() => {
	const n = list.value[Number(index.value)]
	if (n) {
		return markdownhtml(n) as Studycodemodel.Imatchquestion
	}
	return null
});
function setuserdata(key: string, context: any) {
	userdata[key] = context;
}

const savetime = ref()
// 保存时间 按钮用-暂时妹移植
const saveloading = ref(false)

watch(userdata, () => {
	if (!p.match.ID) {
		return;
	}
	saveloading.value = true
	asyncsavetmpmatchuserdata({
		activityid: p.match.ID,
		data: userdata,
		seconds: 1000 * 60 * 60 * 24,
	}).then((e) => {
		saveloading.value = false
		savetime.value = moment().format('HH:mm:ss')
		const t: IWsEmitatactivity = "atactivity";
		store.state.socket.emit(t, {
			activityid: p.match.ID,
			userid: store.state.user?.ID,
		});
	});
});

watch(
	() => index.value,
	(e) => {
		if (Number(p.index) > list.value.length) {
			console.log("题目序号超过列表长度！！！")
			router.push({
				name: "比赛答题",
				params: {
					index: 0,
				},
			});
		}
		// 当前在哪儿一题
		currCheckUq.value = userQuestion.value[Number(e)]
	}
);

// 是否自动提交
watch(() => p.sub, () => {
	if (user.value) {
		// submit();
		_submit();
	}
}
);
const hanzi = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '百']

function save() {
	if (!p.match.ID) {
		return;
	}
	if (ques.value?.context) {
		if (ques.value.context && question.value?.ID) {
			userdata[question.value.ID] = assign({}, userdata[question.value.ID], {
				context: ques.value.context,
				language: ques.value.language || "CPP",
				gccoptimize: ques.value.gccoptimize
			})
		}
	}
}

// 提交试题、试卷 false为提交题目
const isSubmitPaper = ref()
async function submit(b = true) {
	isSubmitPaper.value = b;
	// 提交题目
	if (!isSubmitPaper.value) {
		_submit(b);
		return;
	}
	// 提交试卷
	// 弹窗 试卷提交内容确认
	dialogVisible.value = true;
	// 设置默认值
	currCheckUq.value = userQuestion.value[Number(index.value)]
}
async function _submit(b = true) {
	if (!p.match.ID) {
		return;
	}
	if (ques.value) {
		if (ques.value.context && question.value?.ID) {
			userdata[question.value.ID] = {
				context: ques.value.context,
				language: ques.value.language || "CPP",
				gccoptimize: ques.value.gccoptimize
			};
		}
	}
	const socket: Socket = store.state.socket;
	const t = list.value.map((v) => {
		const obj: Studycodemodel.Imatchuserquestion = {};
		if (v.ID) {
			const context = userdata[v.ID];
			obj.type = v.type;
			obj.questionid = v.ID;
			obj.info = {};
			if (v.type !== "代码") {
				obj.questionid;
				obj.info.answer = context;
			} else {
				obj.language = context?.language;
				obj.context = context?.context;
				obj.gccoptimize = context?.gccoptimize ? '-O2' : undefined;
				// 比赛的运行测试和提交代码 需要加上是否文件读写
				obj.isfile = p.match.isfile || false;
			}
			return obj;
		}
		return {};
	});
	if (!b) {
		// socket.emit("match", {
		//   activityid: p.match.ID,
		//   data: [t[Number(index.value)]],
		//   userid: user.value.ID,
		// });
		try {
			await asyncSaveMatch({
				activityid: p.match.ID,
				data: [t[Number(index.value)]],
				userid: user.value.ID,
			})
			ElMessage.success("提交成功");
		} catch (error) {
			ElMessage.error("提交失败");
		}
		return '只提交当前题目'
	}

	// 如果强制提交
	// if (p.sub && socket) {
	//   socket.emit("match", {
	//     activityid: p.match.ID,
	//     data: t,
	//     userid: user.value.ID,
	//   });
	//   router.push({ name: "比赛结束" });
	//   return;
	// }
	if (p.sub) {
		try {
			await asyncSaveMatch({
				activityid: p.match.ID,
				data: t,
				userid: user.value.ID,
			})
			ElMessage.success("提交成功");
			router.push({ name: "比赛结束" });
		} catch (error) {
			ElMessage.error("提交失败");
		}
		return;
	}
	ElMessageBox.confirm(`
		<div class="">是否要提交试卷？</div>
		<div>
			${p.match.format === 'IOI'
			? '<b class="custom-content-r">提交试卷后即结束本次比赛</b>'
			: '<b>提交试卷后即结束本次比赛，且 <span class="custom-content-r">无法再次进入比赛。</span></b>'}
		</div>`,
		'提交试卷',
		{
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			dangerouslyUseHTMLString: true,
			customClass: 'custom-message-box',
			// 可选的回调函数，可以根据需求来添加
			// callback: (action) => {
			//   console.log(action)
			// }
		})
		.then(async () => {
			if (!p.match.ID) {
				return;
			}
			console.log(t)
			// socket.emit("match", {
			//   activityid: p.match.ID,
			//   data: t,
			//   userid: user.value.ID,
			// });
			try {
				await asyncSaveMatch({
					activityid: p.match.ID,
					data: t,
					userid: user.value.ID,
				})
				ElMessage.success("提交成功");
			} catch (error) {
				ElMessage.error("提交失败");
				return;
			}
			const arr: [string, any][] = [];

			arr[0] = ["_method_", "match"];
			arr[1] = ["type", "scoket"];
			arr[2] = ["ismatch", true];
			arr[3] = ["matchid", p.match.ID];
			arr[4] = ["matchname", p.match.name];
			jilurizhi(arr);
			router.push({ name: "比赛结束" });
		})
		.catch((e: any) => {
			// ElMessage({ type: 'info', message: '取消提交', })
		});
}

async function Mounted() {
	await p.start();
	if (!user.value) {
		ElMessage.error("请登录");
		router.push("/");
	}
	if (!p.match?.ID) {
		router.push("/");
		return;
	}
	if (p.match) {
		const d = p.match.activityuser?.find((v) => v.ID == user.value.ID);
		if (d) {
			ElMessage.error("没有报名");
			router.push("/");
		}
	}
	if (isnot.value.err) {
		ElMessage.error(isnot.value.msg);
		router.push("/");
	}
	const [data] = await asyncselectmatchquestion({ activityid: p.match.ID, });
	if (data) {
		list.value =
			data.matchquestion?.sort((a, b) => Number(a.paixu) - Number(b.paixu)).map((f, k) => {
				if (!p.match.isshowquestionname) {
					return {
						...f,
						name: `第${k + 1}题`
					}
				}
				return f
			}) || [];
	}
	if (list.value.length === 0) {
		ElMessage.error("此次比赛已结束");
		router.push("/");
	}
	asyncgettmpmatchuserdata({
		activityid: p.match.ID,
	})
		.then((olddata = {}) => {
			Object.assign(userdata, olddata);
			// 缓存数据获取
			let id;
			if (question.value?.ID) {
				const data = (olddata as any)[question.value.ID];
				if (data) {
					id = data;
				}
			}
			if (ques.value) {
				if (!ques.value.context) {
					ques.value.context = id?.context;
					ques.value.language = id?.language || "CPP";
					// console.log("同步缓存", id, id?.gccoptimize)
					// 为什么gccoptimize是  缓存没有才勾上 有就不勾选
					// ques.value.gccoptimize = id?.gccoptimize === undefined ? true : false
					ques.value.gccoptimize = id?.gccoptimize ? true : false
				}
			}
			if (select.value) {
				if (!select.value.data) {
					select.value.data = id;
				}
			}
		})
		.catch((e) => {
			console.error(e);
		});
}

onMounted(() => {
	Mounted();
});

// 试卷提交内容确认
const dialogVisible = ref(false);
const userQuestionChecked = ref(false);
function toSubmit() {
	userQuestionChecked.value = true;
	_submit(isSubmitPaper.value);
}

const userQuestion = computed(() => {
	return list.value.map((e, i) => {
		console.log("userQuestion", e, i, userdata[e.ID])
		if (e.ID) {
			const isCode = e.type === '代码';
			const mySubmitRaw = userdata[e.ID]; // 获取题目 ID 的原始数据
			// 提取代码题的 context，其他类型使用原始值
			const mySubmit = isCode ? (mySubmitRaw?.context || "") : (mySubmitRaw || "");
			// 对于代码题显示字节大小，对于非代码题显示答案的字符串表示形式
			const displayInBytesColumn = isCode ? `${new Blob([mySubmit]).size} 字节` : mySubmit;

			const ret = {
				index: i, ID: e.ID, context: e.context, mySubmit, // mySubmit 保存实际的代码或答案值
				type: e.type,
				bytes: displayInBytesColumn, // 在 'bytes' 列中显示大小或答案字符串
				language: userdata[e.ID]?.language
			};
			// 不能直接对外部变量（如 rowData.value）进行赋值，因为计算属性是基于依赖的 缓存 机制的。它只会在其依赖的响应式数据发生变化时 重新计算，并且计算过程中不能进行副作用操作（比如修改其他的响应式变量）。
			// if (!i && !rowData.value) {
			// 	rowData.value = ret
			// }
			return ret
		}
	});
});

const currCheckUq = ref()
function clickRow(row: any, column: any, event: Event): void {
	if (currCheckUq.value?.ID !== row.ID) {
		currCheckUq.value = row
		return
	}
	currCheckUq.value = {}
}
function toQuestion() {
	router.push({ name: '比赛答题', params: { index: currCheckUq.value.index, }, });
	dialogVisible.value = false
}

function rowClassName({ row, rowIndex }: { row: any, rowIndex: number }): string {
	let className = 'cursor-pointer'
	if (currCheckUq.value?.ID === row.ID) {
		className = 'highlight-row cursor-pointer'; // 
	}
	return className;
};

</script>

<style scoped>
.dialog-body {
	border: 1px solid #ccc;
	height: 75vh;
	/* height: calc(80vh - 60px); */
}

.dialog-body-right,
.dialog-body-left {
	/* max-height: 70vh; */
	height: 100%;
}

.dialog-body-right {
	border-left: 1px solid #ccc;
}

.to-question {
	margin: 10px;
	display: flex;
	justify-content: flex-end;
}

.mySubmit {
	/* max-height: 50vh; */
}

.dialog-footer {
	display: flex;
	align-items: center;
	justify-content: center;
}
</style>
<style>
.custom-message-box .custom-content-r {
	/* font-size: 16px;
  font-weight: bold; */
	color: red;
}

.dialog .dialog-body-left img {
	max-width: 350px;
}
</style>